package com.gjzhao.fmmall.controller;

import com.gjzhao.fmmall.vo.RespResultVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @Description: 线程池处理用户请求
 * @Author: gjzhao
 * @Date Created in 2022-03-05 9:50 上午
 */
@RestController
@Api(value = "线程池处理用户请求", tags = "线程池管理")
@CrossOrigin
public class ThreadPoolController extends BaseController {

    @GetMapping("/testJDKThreadPool")
    @ApiOperation(value = "jdk自带线程池")
    public RespResultVO testJDKThreadPool() {

        logger.info("-----当前服务器的CPU核心数量:{}----", Runtime.getRuntime().availableProcessors());

        //使用JDK自带的 Executors 工具类创建线程池
        ExecutorService threadPool = null;

        try {
            //1.创建线程池
            //由于该方式队列的初始化大小为2的30次方左右，所以在高并发场景下及其容易导致OOM异常
            threadPool = Executors.newFixedThreadPool(5);

            logger.info("-----已创建完成线程池:{}---", threadPool);

            for (int i = 0; i < 12; i++) {

                final int finalI = i;

                //2.使用线程: Runnable 为函数式接口，可使用下面书写方式
                //execute方式执行无返回值
                threadPool.execute(() -> {

                    logger.info("---当前线程:{},处理用户请求:{}----", Thread.currentThread().getName(), finalI);

                    try {
                        Thread.sleep(1000);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                });
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {

            if (threadPool != null) {

                logger.info("-----关闭线程池资源---");

                //3.使用完后需要关闭
                threadPool.shutdown();
            }

        }

        return RespResultVO.success();
    }

    @GetMapping("/testCustomThreadPool")
    @ApiOperation(value = "自定义线程池")
    public RespResultVO testCustomThreadPool() {

        //当前cpu核数为12
        //logger.info("-----当前服务器的CPU核心数量:{}----", Runtime.getRuntime().availableProcessors());

        //自定义线程池
        ExecutorService threadPool = null;

        try {

            //1.创建线程池
            threadPool = new ThreadPoolExecutor(3,
                                                13,
                                                1000,
                                                TimeUnit.SECONDS,
                                                new LinkedBlockingQueue<Runnable>(5),
                                                Executors.defaultThreadFactory(),
                                                new ThreadPoolExecutor.DiscardPolicy()
            );


            for (int i = 0; i < 20; i++) {

                final int finalI = i;

                //2.使用线程: Runnable 为函数式接口，可使用下面书写方式
                threadPool.execute(() -> {
                    logger.info("---当前线程:{},处理用户请求:{}----", Thread.currentThread().getName(), finalI);
                    try {
                        Thread.sleep(1000);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                });
            }


        } catch (Exception e) {
            e.printStackTrace();
        } finally {

            if (threadPool != null) {
                //使用完后需要关闭
                threadPool.shutdown();
            }

        }

        return RespResultVO.success();
    }
}
